/**
 * CS 6310 
 * Facebook Connection
 * Integration Testing
 * 
 * The FacebookIntegration java class gives the efficient way of accessing facebook data 
 * like accounts, frindslist, news feed, and events details.
 * 
 * The connections used: "me/accounts", "me/friends", "me/feed", and "me/events"
 * 
 * Here, I am using FQL Facebook Query Language to get the event's attendess 
 * instaed of using "eid/attending" connection. 
 * 
 * @author Yoga</a>
 * @param <T>
 */

package com.IntegrationFacebook;

import static java.lang.System.out;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.restfb.Connection;
import com.restfb.DefaultFacebookClient;
import com.restfb.Facebook;
import com.restfb.FacebookClient;
import com.restfb.example.GraphReaderExample.FqlLiker;
import com.restfb.example.GraphReaderExample.FqlUser;
import com.restfb.types.FacebookType;
import com.restfb.types.NamedFacebookType;
import com.restfb.types.Post;
import com.restfb.types.User;
import com.restfb.types.Event;

public class FacebookIntegration<T> { 
private final FacebookClient facebookClient;

 @SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
	  if (args.length == 0)
		  throw new IllegalArgumentException("You must provide an OAuth access token parameter. "   + "See README for more information.");
    
	  String[] args1  = {"2227470867|2.J9Dv1Fs7wSTmQNfTYVM5yw__.3600.1299888000-1564863831|T-ATwyIEkP7SErWDYr5h94FQEuo"}; //My access token
	  	    
	  String conn1 = "me/friends";
	  String conn2 = "me/feed";
	  String conn3 = "me/events";
	  String conn4 = "me/accounts";
	  Class connType1 = User.class;
	  Class connType2 = Post.class;
	  Class connType3 = Event.class;
	  Class connType4 = User.class;

	  new FacebookIntegration(args1[0]).runConnection(conn4,connType4 );
 }

 public FacebookIntegration(String accessToken) {
	 facebookClient = new DefaultFacebookClient(accessToken);
	 }    
    
 public static class MultiqueryResults {
	    @Facebook
	    List<FqlUser> users;
	    @Facebook
	    List<FqlLiker> likers;	    
	    @Facebook
	    List<FqlLiker> events;
	    @Facebook
	    List<FqlLiker> accounts;					    
	  }
 
@SuppressWarnings({ "hiding" })
public <T>Connection<T> runConnection(String connection, Class<T> connectionType){
	
	//My account details including access token of others
	if (connection == "me/accounts")
	{
		out.println("acessing...ACCOUNTS...");
		Connection<T> myAccounts = facebookClient.fetchConnection(connection, connectionType);
		out.println("Count of my accounts:" + myAccounts.getData().size());
		out.println("My accounts data as a string:" + myAccounts.getData().toString());
	
		Map<String, String> queries = new HashMap<String, String>();
	    queries.put("accounts", "SELECT developer_id FROM developer WHERE application_id=167699919949156");
	    MultiqueryResults multiqueryResults = facebookClient.executeMultiquery(queries, MultiqueryResults.class);
	    out.println("Accounts: " + multiqueryResults.accounts);
		
		
	}
	
	if (connection == "me/friends")
	{
		out.println("acessing...FRIENDS...");
		Connection<T> myFriends = facebookClient.fetchConnection(connection, connectionType);
		out.println("Count of my friends:" + myFriends.getData().size());
		out.println("My frinds data as a string:" + myFriends.getData().toString());
	
	}
	if (connection == "me/feed")
	{
		out.println("accessing...FEED...");
		Connection<T> myFeed = (Connection<T>) facebookClient.fetchConnection(connection, connectionType);
		out.println("My feed ID: " + ((FacebookType) myFeed.getData().get(0)).getId());
		out.println("My feed Name: " + ( (NamedFacebookType) myFeed.getData().get(0)).getName());
		out.println("My feed Link: " + ( (User) myFeed.getData().get(0)).getLink());
		out.println("My feed Type: " + ( (FacebookType) myFeed.getData().get(0)).getType());
		out.println("My feed ID: " + ( myFeed.getData().toString()));
		
		Map<String, String> queries = new HashMap<String, String>();
	    queries.put("users", "SELECT uid, name FROM user WHERE uid=653615817");
	    MultiqueryResults multiqueryResults = facebookClient.executeMultiquery(queries, MultiqueryResults.class);
	    out.println("Users: " + multiqueryResults.users);
	 }
	if (connection == "me/events")
	{
		out.println("accessing...EVENTS...");
		//My Event details 
		Connection<T> myEvent = (Connection<T>) facebookClient.fetchConnection(connection, connectionType);
		out.println("My event ID: " + ((Event) myEvent.getData().get(0)).getId());
		
		//Storing event id in variable.
		String event_id = ((Event) myEvent.getData().get(0)).getId();
		
		//Event details
		out.println("My event Name: " + ((Event) myEvent.getData().get(0)).getName());
		out.println("My event Location: " + ((Event) myEvent.getData().get(0)).getLocation());
		out.println("My event StartTime: " + ((Event) myEvent.getData().get(0)).getStartTime());
		out.println("My event EndTime: " + ((Event) myEvent.getData().get(0)).getEndTime());
	
		//Method 1 - Using eid/attending connection
		//Creating eid/Attending connection per event 
	    String connection1 = event_id+"/attending";
	    Connection<Event> myAttending = (Connection<Event>) facebookClient.fetchConnection(connection1, Event.class);
	    //Event Attending details as string
	    out.println("My attending: " + ( myAttending.getData().toString()));
	    
	    //Method 2 - Using FQL Facebook Query Language
	    //Evevt info using FQL by event id 
	    Map<String, String> queries = new HashMap<String, String>();
		queries.put("events", "SELECT eid, name, event_type, start_time, end_time,location FROM event WHERE eid="+event_id);
	    MultiqueryResults multiqueryResults = facebookClient.executeMultiquery(queries, MultiqueryResults.class);
	    out.println("My event details: " + multiqueryResults.events);
	}		
	
return null;
}
}

